const path = require('path');
const htmlWebpackPlugin = require('html-webpack-plugin');                       // 导入在内存中生成页面的插件
const { CleanWebpackPlugin } = require('clean-webpack-plugin');                 // 导入删除文件夹的插件
const MiniCssExtractPlugin = require('mini-css-extract-plugin');                // 导入抽取css样式文件的插件
const OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin');  // 导入压缩css文件的插件
const { VueLoaderPlugin } = require('vue-loader')

// 注意：这里使用了node的语法，向外暴露了一个配置对象
// 因为webpack这个构建工具，底层是使用node.js开发的
module.exports = {
    mode: 'production',     // Sets process.env.NODE_ENV on DefinePlugin to value production.
    entry: path.resolve(__dirname, 'src/index.js'),
    output: {
        // filename使用"[name].js"避免文件名产生冲突
        // 否则报错 Conflict: Multiple chunks emit assets to the same filename index.js (chunks 1 and 2)
        filename: 'js/[name].js',
        path: path.resolve(__dirname, 'dist'),
    },
    plugins: [
        new htmlWebpackPlugin({ // 创建一个把html首页托管到内存中的插件
            template: path.resolve(__dirname, './src/index.html'),
            filename: "index.html",
            minify: {   // 压缩html代码
                collapseWhitespace: true,       // 合并空白字符
                removeComments: true,           // 移除注释
                removeAttributeQuotes: true     // 移除属性上的引号
            }
        }),
        // All files inside webpack's output.path directory will be removed once, but the directory itself will not be. If using webpack 4+'s default configuration, everything under <PROJECT_DIR>/dist/ will be removed.
        new CleanWebpackPlugin(),        // 指定每次打包前要删除的文件夹，默认为output.path文件夹
        new MiniCssExtractPlugin({
            filename: "css/styles.css"      // 将抽离的css文件放在css文件夹中
        }),
        new OptimizeCssAssetsPlugin(),       // 自动压缩css文件
        new VueLoaderPlugin()
    ],
    optimization: {
        splitChunks: {
            // async: 只对异步模块进行优化打包
            // initial: 分开优化打包异步和非异步模块
            // all: 把异步和非异步同时进行优化打包
            // 当moduleA在indexA中异步引入，indexB中同步引入，initial下moduleA会出现在两个打包块中，而all只会出现一个
            chunks: "all",
            cacheGroups: {
                vendors: {
                    // 这里重写了vendors打包块，只打包匹配jquery的模块，不修改vendors情况下默认匹配所有来自node_modules的模块
                    test: /vue|vuex|vue-preview|moment|mint-ui|axios/,
                    name: "vendors"        // 指定抽离第三方包的入口名称
                }
            }
        },
        // Tell webpack to minimize the bundle using the TerserPlugin or the plugin(s) specified in optimization.minimizer.
        minimize: true
    },
    module: {   // 用来配置非JS文件对应的loader的
        rules: [    // 就是这些非JS文件和loader之间的对应关系
            {   // css文件的loader匹配规则
                test: /\.css$/i, use: [{
                    loader: MiniCssExtractPlugin.loader,
                    options: {
                        publicPath: '../',      // 表示如果将来生成的样式中包含路径，那么需要自动在路径前加上../前缀
                    },
                }, 'css-loader']
            },
            {   // less文件的loader匹配规则
                test: /\.less$/i, use: [{
                    loader: MiniCssExtractPlugin.loader,
                    options: {
                        publicPath: '../',
                    },
                }, "css-loader", "less-loader"]
            },
            {   // scss文件的loader匹配规则
                test: /\.scss$/i, use: [{
                    loader: MiniCssExtractPlugin.loader,
                    options: {
                        publicPath: '../',
                    },
                }, "css-loader", "sass-loader"]
            },
            // 样式表中图片的loader匹配规则
            // 可使用?给url-loader传参，其中有一个固定的参数为limit，表示图片的大小，需要给定一个数值
            // limit给定的这个数值，是图片的大小，单位是Byte（字节）
            // 如果指定了limit参数，则只有图片的大小小于或者等于给定的值时，才会转为base64格式的图片；否则就不转换
            { test: /\.jpg|png|gif|bmp$/i, use: 'url-loader?limit=5859&name=images/[hash:8]-[name].[ext]&esModule=false' },
            // Babel转换高级语法到低级语法
            { test: /\.js$/i, use: "babel-loader", exclude: /node_modules/ },
            { test: /\.vue/, use: "vue-loader" },               // 解析Vue组件的第三方loader
            { test: /\.ttf|woff|woff2|eot|svg$/, use: 'url-loader' }        // 处理样式中字体文件路径的问题
        ]
    }
};